package com.glidebitmappool.internal;

import ohos.media.image.PixelMap;
import ohos.media.image.common.ImageInfo;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;

/**
 * 位图池属性类
 *
 * @author renpengfei
 * @since 2021-03-12
 */
public class AttributeStrategy implements LruPoolStrategy {
    private final KeyPool keyPool = new KeyPool();
    private final GroupedLinkedMap<Key, PixelMap> groupedMap = new GroupedLinkedMap<>();

    /**
     * put
     *
     * @param bitmap 图片
     */
    @Override
    public void put(PixelMap bitmap) {
        // 获取位图宽、高、以及其他配置信息
        ImageInfo imageInfo = bitmap.getImageInfo();
        Size size = imageInfo.size;
        final Key key = keyPool.get(size.width, size.height, imageInfo.pixelFormat);

        groupedMap.put(key, bitmap);
    }

    /**
     * get
     *
     * @param width 宽
     * @param height 高
     * @param config 格式
     * @return PixelMap
     */
    @Override
    public PixelMap get(int width, int height, PixelFormat config) {
        final Key key = keyPool.get(width, height, config);

        return groupedMap.get(key);
    }

    /**
     * removeLast
     *
     * @return PixelMap
     */
    @Override
    public PixelMap removeLast() {
        return groupedMap.removeLast();
    }

    /**
     * logBitmap
     *
     * @param bitmap
     * @return String
     */
    @Override
    public String logBitmap(PixelMap bitmap) {
        return getBitmapString(bitmap);
    }

    /**
     * logBitmap
     *
     * @param width 宽
     * @param height 高
     * @param config 格式
     * @return String
     */
    @Override
    public String logBitmap(int width, int height, PixelFormat config) {
        return getBitmapString(width, height, config);
    }

    /**
     * 获取图片大小
     *
     * @param bitmap
     * @return int
     */
    @Override
    public int getSize(PixelMap bitmap) {
        return Util.getBitmapByteSize(bitmap);
    }

    /**
     * toString
     *
     * @return String
     */
    @Override
    public String toString() {
        return "AttributeStrategy:" + System.lineSeparator() + groupedMap;
    }

    /**
     * getBitmapString
     *
     * @param bitmap
     * @return String
     */
    private static String getBitmapString(PixelMap bitmap) {
        // 获取位图宽、高、以及其他配置信息
        ImageInfo imageInfo = bitmap.getImageInfo();
        Size size = imageInfo.size;
        return getBitmapString(size.width, size.height, imageInfo.pixelFormat);
    }

    private static String getBitmapString(int width, int height, PixelFormat config) {
        return "[" + width + "x" + height + "], " + config;
    }

    /**
     * 测试使用
     *
     * @since 2021-03-12
     */
    static class KeyPool extends BaseKeyPool<Key> {
        public Key get(int width, int height, PixelFormat config) {
            Key result = get();
            result.init(width, height, config);
            return result;
        }

        @Override
        protected Key create() {
            return new Key(this);
        }
    }

    /**
     * 测试使用
     *
     * @since 2021-03-12
     */
    static class Key implements Poolable {
        private final KeyPool pool;
        private int width;
        private int height;

        // Config can be null
        private PixelFormat config;

        Key(KeyPool pool) {
            this.pool = pool;
        }

        public void init(int width1, int height1, PixelFormat pixelFormat) {
            this.width = width1;
            this.height = height1;
            this.config = pixelFormat;
        }

        @Override
        public boolean equals(Object object) {
            if (object instanceof Key) {
                Key other = (Key) object;
                return width == other.width && height == other.height && config == other.config;
            }
            return false;
        }

        @Override
        public int hashCode() {
            int result = width;
            result = 31 * result + height;
            result = 31 * result + (config != null ? config.hashCode() : 0);
            return result;
        }

        @Override
        public String toString() {
            return getBitmapString(width, height, config);
        }

        @Override
        public void offer() {
            pool.offer(this);
        }
    }
}
